#ifndef __WIZ_DATATYPE_STACK_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_STACK_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"
#include "./WizDataTypeForEach.hpp"
#include "./WizDataTypeArray.hpp"
#include "./WizDataTypeList.hpp"
#include "./WizDataTypeDeque.hpp"
#include "./WizDataTypeSet.hpp"

namespace Wiz
{
    namespace Stack
    {
        enum eStackType 
        {
            eStackTypeArray,
            eStackTypeList,
        };

        template<class ElementT, eStackType = eStackTypeArray>
        struct Type{};

        template<class ElementT>
        struct Type<ElementT, eStackTypeArray> : private ::Wiz::Array::Type<ElementT>
        {
            WIZ_DECLARE_CLASS_THIS(Type);
            //////////////////////////////////////////////////////////////////////////
            typedef ::Wiz::Array::Type<ElementT>                       tSuper;
            typedef typename tSuper::tValue                     tValue;
            typedef typename tSuper::tIterator                  tIterator;
            typedef typename tSuper::tIteratorConst             tIteratorConst;
            typedef typename tSuper::tValueConst                tValueConst;
            typedef typename tSuper::tReference                  tReference;

            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            typedef ::Wiz::ForEach::Type<::Wiz::Stack::Type<ElementT, eStackTypeArray>>         tForEach;
            typedef ::Wiz::ConstForEach::Type<::Wiz::Stack::Type<ElementT, eStackTypeArray>>    tForEachConst;
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            tIterator Begin()
            {
                return tSuper::Begin();
            }

            tIteratorConst Begin() const
            {
                return tSuper::Begin();
            }

            tIterator End()
            {
                return tSuper::End();
            }

            tIteratorConst End() const
            {
                return tSuper::End();
            }

            ///-----------------------///

            ::Wiz::Size::Type Size() const
            {
                return tSuper::Size();
            }

            ::Wiz::Void::Type Clear()
            {
                tSuper::Clear();
            }

            tIterator Erase(tIterator itr)
            {
                return tSuper::Erase(itr);
            }

            ///-----------------------///

            ::Wiz::Void::Type Push(const ElementT& v)
            {
                tSuper::PushBack(v);
            }

            ::Wiz::Void::Type Pop()
            {
                tSuper::PopBack();
            }

            tReference Top()
            {
                return tSuper::Back();
            }

            tReference Top() const
            {
                return tSuper::Back();
            }
        };

        template<class ElementT>
        struct Type<ElementT, eStackTypeList> : private ::Wiz::List::Type<ElementT>
        {
            WIZ_DECLARE_CLASS_THIS(Type);
            //////////////////////////////////////////////////////////////////////////
            typedef ::Wiz::List::Type<ElementT>                     tSuper;
            typedef typename tSuper::tIterator                      tIterator;
            typedef typename tSuper::tIteratorConst                 tIteratorConst;
            typedef typename tSuper::tValue                         tValue;
            typedef typename tSuper::tValueConst                    tValueConst;
            typedef typename tSuper::tReference                     tReference;
            //////////////////////////////////////////////////////////////////////////
            typedef ::Wiz::ForEach::Type<::Wiz::Stack::Type<ElementT, eStackTypeList>>         tForEach;
            typedef ::Wiz::ConstForEach::Type<::Wiz::Stack::Type<ElementT, eStackTypeList>>    tForEachConst;
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            tIterator Begin()
            {
                return tSuper::Begin();
            }

            tIteratorConst Begin() const
            {
                return tSuper::Begin();
            }

            tIterator End()
            {
                return tSuper::End();
            }

            tIteratorConst End() const
            {
                return tSuper::End();
            }

            ///-----------------------///

            ::Wiz::Size::Type Size() const
            {
                return tSuper::Size();
            }

            ::Wiz::Void::Type Clear()
            {
                tSuper::Clear();
            }

            tIterator Erase(tIterator itr)
            {
                return tSuper::Erase(itr);
            }

            ///-----------------------///

            ::Wiz::Void::Type Push(const ElementT& v)
            {
                tSuper::PushFront(v);
            }

            ::Wiz::Void::Type Pop()
            {
                tSuper::PopFront();
            }

            tReference Top()
            {
                return tSuper::Front();
            }

            tReference Top() const
            {
                return tSuper::Front();
            }
        };
    } /// end of namespace Stack
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_STACK_HPP__SHANHAOBO_19800429__*/
